import { NestFactory } from '@nestjs/core'
import { ConfigService } from '@donews/nestjs-config'
import bodyParser from 'body-parser'
import rateLimit from 'express-rate-limit'
import helmet from 'helmet'
import { AppModule } from './app.module'
import { getIp, onProcess } from './bootstrap'
import {
    CustomLoggerService,
    HealthService,
    HttpExceptionFilter,
    AnyExceptionFilter,
    CoreExceptionFilter,
    ResponseInterceptor,
    RequestInterceptor,
} from '@/modules'
import { ValidationPipe } from '@nestjs/common'

export let logger: CustomLoggerService

async function main() {
    const app = await NestFactory.create(AppModule)
    const config = app.get(ConfigService)
    logger = app.get(CustomLoggerService)

    onProcess(app)

    const global = config.get('global', {
        prefix: 'none',
        maxrate: 999,
        enableCors: true,
        enableHelmet: true,
        bodyLimit: '2mb',
    })
    const service = config.get('service', {
        port: 8800,
        discoveryHost: 'localhost',
    })

    // 注册全局异常过滤器
    app.useGlobalFilters(
        new AnyExceptionFilter(logger),
        new HttpExceptionFilter(logger),
        new CoreExceptionFilter(logger),
    )

    // 注册全局拦截器
    app.useGlobalInterceptors(new RequestInterceptor(config), new ResponseInterceptor(logger))

    // 注册全局验证器
    app.useGlobalPipes(
        new ValidationPipe({
            transform: true,
            // whitelist: false,
        }),
    )

    // 调整请求体限制
    app.use(bodyParser.json({ limit: global.bodyLimit }))
    app.use(bodyParser.urlencoded({ limit: global.bodyLimit, extended: true }))

    // 允许跨域
    if (global.enableCors) {
        app.enableCors()
    }

    // 暴力攻击限速保护
    if (global.maxrate > 0) {
        app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: global.maxrate }))
    }

    // HTTP请求安全防护。（XSS/HSTS/HPKP/DNS/FRAME等）
    if (global.enableHelmet) {
        app.use(helmet())
    } else {
        app.use(helmet({ frameguard: false }))
    }

    // 项目版本号命名API
    if (global.prefix !== 'none') {
        app.setGlobalPrefix(global.prefix)
    }

    // 健康检查【磁盘】
    const healthService = app.get(HealthService)
    app.getHttpAdapter().get('/health', async (_, res) => {
        try {
            const result = await healthService.healthCheck()
            return res.status(200).json(result)
        } catch (error) {
            return res.status(500).json(error.response)
        }
    })

    await app.listen(service.port)

    logger.log(`[服务初始化] - 请求限制：${global.bodyLimit};`)
    logger.log(`[服务初始化] - 允许跨域：${global.enableCors ? 'ON' : 'OFF'};`)
    logger.log(`[服务初始化] - 接口限速：${global.maxrate > 0 ? global.maxrate : 'OFF'};`)
    logger.log(`[服务初始化] - 安全防护：${global.enableHelmet ? 'ON' : 'OFF'};`)
    logger.log(`[服务初始化] - 接口版本：${global.prefix ? global.prefix : 'OFF'};`)
    logger.log(`[服务初始化] - 启动成功：监听 - http://${service.discoveryHost || getIp()}:${service.port}`)
}

main()
